﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Packaging;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using AdminApp.Web.Services;
using TheOliver.DigitalSignage.Client.Interfaces;
using TheOliver.DigitalSignage.Client.Logic;
using TheOliver.DigitalSignage.Client.Windows;

namespace TheOliver.DigitalSignage.Client
{
    public partial class MainPage : UserControl
    {
        DispatcherTimer _mouseMoveTimer;

        PackageCatalog packageCatalog;

        public MainPage()
        {
            InitializeComponent();

            #region Packaging Catalog

            packageCatalog = new PackageCatalog();
            CompositionContainer cc = new CompositionContainer(packageCatalog);
            CompositionHost.InitializeContainer(cc);

            PartInitializer.SatisfyImports(this);

            #endregion

            #region MouseMove & Menu Display

            _mouseMoveTimer = new DispatcherTimer();
            _mouseMoveTimer.Interval = new System.TimeSpan(0, 0, 3);
            _mouseMoveTimer.Tick += (s, e) =>
                {
                    _mouseMoveTimer.Stop();
                    _menuOverlay.Visibility = System.Windows.Visibility.Collapsed;
                    this.Cursor = Cursors.None;
                };
            
            _menuOverlay.Visibility = Visibility.Collapsed;
            this.MouseMove += (s, e) =>
                {
                    if (_menuOverlay.Visibility == System.Windows.Visibility.Collapsed)
                    {
                        _menuOverlay.Visibility = System.Windows.Visibility.Visible;
                        this.Cursor = Cursors.Arrow;
                    }
                    _mouseMoveTimer.Stop();
                    _mouseMoveTimer.Start();
                };

            #endregion

            #region Out of Browser - Button

            if (App.Current.IsRunningOutOfBrowser ||
                App.Current.InstallState == InstallState.Installed)
            {
                _installOutOfBrowser.Visibility = System.Windows.Visibility.Collapsed;
            }

            #endregion

            #region Installation State Changed

            App.Current.InstallStateChanged += (s, e) =>
                {
                    if (App.Current.InstallState != InstallState.Installed)
                    {
                        _installOutOfBrowser.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        _installOutOfBrowser.Visibility = Visibility.Collapsed;
                    }
                };

            #endregion

            #region Check for Update & Select Event

            if (App.Current.IsRunningOutOfBrowser)
            {
                App.Current.CheckAndDownloadUpdateCompleted += (s, e) =>
                    {
                        if (e.UpdateAvailable)
                        {
                            MessageBox.Show(TextResource.UpdatedVersionAvailable);
                        }
                        else
                        {
                            SetEvent();
                        }
                    };
                
                App.Current.CheckAndDownloadUpdateAsync();
                // TODO: Show that app checks for update
            }
            else
            {
                this.Loaded += (s2, e2) =>
                {

                    if (Configuration.SelectedEvent != null
                        && Configuration.SelectedRoom != null)
                    {
                        LoadCustomDll();
                    }
                    else
                    {
                        SetEvent();
                    }
                };
            }

            #endregion

            #region Rotator

            _rotator.ComponentsLoaded += (s, e) =>
                {
                    _rotator.Start();
                };

            #endregion
        }

        private void SetEvent()
        {
            
            // Set Event
            SelectEventWindow ew = new SelectEventWindow();
            ew.Closed += (s, e) =>
            {
                if (ew.DialogResult.Value == true)
                {
                    // Set Room
                    SelectRoomWindow rw = new SelectRoomWindow();
                    rw.Closed += (s1, e1) =>
                    {
                        if (rw.DialogResult.Value == true)
                        {
                            // Try to load Custom DLL
                            LoadCustomDll();
                        }
                    };
                    rw.Show();
                }
            };

            ew.Show();
        }

        private void LoadCustomDll()
        {
            DigitalSignageDomainContext context = new DigitalSignageDomainContext();
            
            var call = context.GetCustomDllPath(Configuration.SelectedEvent.Name,
                Configuration.SelectedRoom == null ? string.Empty : Configuration.SelectedRoom.Name);

            call.Completed += (s, e) =>
            {
                string dllPath = call.Value;

                if (dllPath != string.Empty)
                {
                    Uri uri = new Uri(dllPath, UriKind.Relative);
                    _isBusy.BusyContent = "Loading Package for "
                        + Configuration.SelectedEvent.Name + " - "
                        + Configuration.SelectedRoom.Name;
                    _isBusy.IsBusy = true;
                    Package.DownloadPackageAsync(uri, (args, package) =>
                      {
                          _isBusy.IsBusy = false;
                          if (!args.Cancelled && (args.Error == null))
                          {
                              packageCatalog.AddPackage(package);
                              _rotator.SetPackage(package);
                          }
                          else if (args.Error != null)
                          {
                              Helper.ShowError(args.Error);
                          }
                      });
                }
                else
                {
                    MessageBox.Show("No dll found");
                    _rotator.SetPackage(null);
                }

            };
        }

        #region Menu Buttons Eventhandler

        private void _installOutOfBrowser_Click(object sender, RoutedEventArgs e)
        {
            if (App.Current.InstallState != InstallState.Installed &&
                App.Current.InstallState != InstallState.Installing)
            {
                App.Current.Install();
            }
        }

        private void _showSettings_Click(object sender, RoutedEventArgs e)
        {
            SettingsWindow sw = new SettingsWindow();

            sw.Closed += (s1, e2) => 
                {
                    if (sw.DialogResult.Value)
                    {
                    }
                };
            sw.Show();
        }

        private void _setEvent_Click(object sender, RoutedEventArgs e)
        {
            SetEvent();
        }

        private void _fullscreen_Click(object sender, RoutedEventArgs e)
        {
            App.Current.Host.Content.IsFullScreen =
                !App.Current.Host.Content.IsFullScreen;
        }

        private void _increaseMemory_Click(object sender, RoutedEventArgs e)
        {
            var file = IsolatedStorageFile.GetUserStoreForSite();
            var quota = file.Quota;
            var availableSpace = file.AvailableFreeSpace;
            var result = file.IncreaseQuotaTo(1024 * 1024 * 1024);

            if (!result)
            {
                MessageBox.Show("You need more memory");
            }
        }

        #endregion

    }
}
